--[[
 -- *名称:ThreeTakeSingleTypeAnalyzer
 -- *描述:[XXXXXXXXX]
 -- *版权:Copyright © 2016-2018 深圳市三只小熊科技有限公司 版权所有
 -- *作者:Administrator
 -- *创建日期:2017-11-09
 -- *修改日期:2017-11-09
 ]]
local DdzSuitAnalyzer = require(basePath.."suit/ddzsuitanalyzer");
local ThreeTakeSingleTypeAnalyzer = pokercore.class(DdzSuitAnalyzer,false);
local FourTakeSingleAnalyzer = require(basePath .. "suit/fourtakesingle/fourtakesingletypeanalyzer") ;
ThreeTakeSingleTypeAnalyzer.TUPLE_SIZE = 4 ;
local TUPLE_SIZE = 4 ;
local ThreeTypeAnalyzer = require(basePath.."suit/three/threetypeanalyzer"); --三条
local Cards = require(basePath .. "domain/cards");
local fourTakeSingleTypeAnalyzer = pokercore.new(FourTakeSingleAnalyzer);
--@Override
function ThreeTakeSingleTypeAnalyzer:getSuitType()
	return DdzCardTypes.THREE_TAKE_SINGLE;
end


--@Override
function ThreeTakeSingleTypeAnalyzer:doCheckRule(cards,term,result)
	if (result:getCardNum() == ThreeTakeSingleTypeAnalyzer.TUPLE_SIZE) then -- 四张牌
		local allValues = result:getNoneLaziValueCounter():getAllValues();
		if (#allValues > 2) then -- // 有三种点数
			return false;
		else  -- // 没有，有一种或两种点数
			if (result:getLaziCardNum() == 0) then --	// 没有癞子
				return #(result:getNoneLaziValueCounter():getValuesInCount(3)) > 0;
			elseif (result:getLaziCardNum() == 1) then -- // 一张癞子
				return (#(result:getNoneLaziValueCounter():getValuesInCount(3)) > 0)
						or (#(result:getNoneLaziValueCounter():getValuesInCount(2)) > 0);
			elseif (result:getLaziCardNum() == 2) then -- // 两张癞子
				return true;
			elseif (result:getLaziCardNum() == 3) then --// 三张癞子
				return true;
			else --// 全是癞子
				return (#(result:getLaziValueCounter():getValuesInCount(3)) > 0);
			end
		end
	else 
		return false;
	end
end


--@Override
function ThreeTakeSingleTypeAnalyzer:doAnalysizeLaizi(cards,term,onlyMaxValue)
	local cardsResult = {};
	local result = cards:getResult();
	local laiziCardList = cards:subList(result:getCardNum() - result:getLaziCardNum()+1, result:getCardNum())
	local laiziCardNum = result:getLaziCardNum();
	if (laiziCardNum == 3) then --三张癞子，3***，避免组成炸弹情况就行了
		for valueTemp = PokerGameConstant.NUMBER_2_VALUE, PokerGameConstant.NUMBER_3_VALUE, -1 do
			local valueTempNum = result:getNoneLaziValueCounter():getValueCount(valueTemp);
			for i = 1 , laiziCardNum do
				local ddzCard = laiziCardList[i];
				local needLaiziNum = 3 - valueTempNum; --// 需要填补几个癞子
				if (i <= needLaiziNum) then
					ddzCard:changeCard(valueTemp);
				else 
					ddzCard:changeCard(ddzCard:getNumber());
				end
			end
			local cardsCopy = cards:clone();
			self:analysize(cardsCopy, term);
			table.insert(cardsResult,cardsCopy:clone());
			if (onlyMaxValue) then
				break; -- // 取完最大一组就跳出
			end
		 end
	else
		local allValues = result:getNoneLaziValueCounter():getAllValues();
		for i = #allValues , 1, -1 do
			local valueTemp = allValues[i];
			local valueTempNum = result:getNoneLaziValueCounter():getValueCount(valueTemp);
			local needLaiziNum = 3 - valueTempNum; --// 需要填补几个癞子
			if (laiziCardNum >= needLaiziNum) then -- // 可能癞子不够
				for  j = 1, laiziCardNum do
					local ddzCard = laiziCardList[j];
					if (j <= needLaiziNum) then
						ddzCard:changeCard(valueTemp);
					else 
						ddzCard:changeCard(ddzCard:getNumber());
					end
				end
				local cardsCopy = cards:clone();
				self:analysize(cardsCopy, term);
				table.insert(cardsResult,cardsCopy:clone());
				if (onlyMaxValue) then
					break; --// 取完最大一组就跳出
				end
			end
		end
	end
	return cardsResult;
end


--提牌算法

--@Override
function ThreeTakeSingleTypeAnalyzer:containsPossibleCards( handCards,  term) 
	return  handCards:getResult():getCardNum() >= TUPLE_SIZE;
end
	
--/** 最多使用癞子的数量 */
local MAX_USE_LAIZI_CARD_NUM = 4;

--/** 防重复判定的比例值 参照 int key = count_3_value * TUPLE_WEIGHT + count_1_value; */
local TUPLE_WEIGHT = 1000000;

--/** 癞子权重，区分癞子变成的5 和 原本就是5 */
local LAIZI_WEIGHT = 1000;

--@Override
function ThreeTakeSingleTypeAnalyzer:doListPossibleCards( handCards, term) 
	local cardsResult = {};
	--// 非癞子部分
	local result = handCards:getResult();
	local noneLaiziCardList = handCards:subList(1, result:getNoneCardNum());
	local noneLaiziCards = DdzTypeUtil.createCardsCopy(noneLaiziCardList);
	noneLaiziCards:setResult(handCards:getResult():clone());
	local noneLaiziCardsResult = noneLaiziCards:getResult();
	noneLaiziCardsResult:collectNumber(noneLaiziCards, term);
	--// 癞子部分
	local laiziCardList = handCards:subList(result:getNoneCardNum()+1, result:getCardNum());
	local laiziCards = DdzTypeUtil.createCardsCopy(laiziCardList);
	laiziCards:setResult(handCards:getResult():clone());
	local laiziCardsResult =  laiziCards:getResult();
	laiziCardsResult:collectNumber(laiziCards, term);
	
	local maxLoseValue = 0; -- // 寻找最大遗失的牌 让***5可以出现，但是仅一次
	for  valueTemp = PokerGameConstant.NUMBER_2_VALUE -- // 从小开始
			,PokerGameConstant.NUMBER_3_VALUE, -1 do
		if (result:getNoneLaziValueCounter():getValueCount(valueTemp) == 0) then
			maxLoseValue = valueTemp;
			break;
		end
	end
	local laiziCardNum = result:getLaziCardNum();
	local maxUseLaiziCardNum = MAX_USE_LAIZI_CARD_NUM < laiziCardNum and MAX_USE_LAIZI_CARD_NUM or laiziCardNum;
	local exsitKeys = {} ;-- // 记录已经组成三带一的value
		for useLaiziCardNum = 0,  maxUseLaiziCardNum do
		if (useLaiziCardNum < MAX_USE_LAIZI_CARD_NUM) then --// 用了 0.1.2.3 个癞子
			for valueTemp = PokerGameConstant.NUMBER_3_VALUE --// 从小开始
					, PokerGameConstant.NUMBER_2_VALUE do
				local modelCardsCopy = noneLaiziCards:clone(); --// 常规牌副本
				local modelResultCopy = modelCardsCopy:getResult();
				local useLaiziCardList = DdzTypeUtil.cloneSublistedCards(laiziCards, 1, useLaiziCardNum); --// 补癞子
				local valueTempNum = modelResultCopy:getNoneLaziValueCounter():getValueCount(valueTemp);
				local needLaiziCardNum = ThreeTypeAnalyzer.TUPLE_SIZE - valueTempNum;
				needLaiziCardNum = needLaiziCardNum > 0 and needLaiziCardNum or 0;
				if (needLaiziCardNum == 0) then
 					local removedCardList = DdzTypeUtil.cloneRemovedCards(modelCardsCopy, valueTemp, ThreeTypeAnalyzer.TUPLE_SIZE);
					local tupleCards = pokercore.new(Cards,removedCardList);
					local remainCards = DdzTypeUtil.cloneCardsAndAddCardList(modelCardsCopy, useLaiziCardList);
					local takenCardsList = fourTakeSingleTypeAnalyzer:repeatSelectSingleCards(remainCards, 1, term);
					for _,takenCards in ipairs(takenCardsList) do
						local resultCards = DdzTypeUtil.cloneCardsAndAddCards(tupleCards, takenCards);
						local key = valueTemp * TUPLE_WEIGHT;
						for _,card in ipairs(takenCards.cardList) do
							key = key + card:getValue();
							if card:isLazi() then -- // 癞子权重，区分癞子变成的5 和 原本就是5
								key = key + card:getValue() * LAIZI_WEIGHT;
							end
						end
						if (not exsitKeys[key] and self:match(resultCards, term)) then
							exsitKeys[key] = true;
							self:analysize(resultCards, term);
							table.insert(cardsResult,resultCards);
						end
					end
				else --// 需要癞子来拼凑
					if (needLaiziCardNum == ThreeTypeAnalyzer.TUPLE_SIZE 
							and valueTemp ~= maxLoseValue) then
						--// 这里是对癞子做tuple的去重
						--// 否则会出现 ***带9 既能是 333带9 也能使 444带9 555带9
						--continue;					
					elseif (useLaiziCardNum >= needLaiziCardNum) then -- // 癞子足够拼凑
						local removedCardList = DdzTypeUtil.cloneRemovedCards(modelCardsCopy, valueTemp, valueTempNum);
						
						for i = 1, needLaiziCardNum do
							local laiziCard = table.remove(useLaiziCardList,1);
							laiziCard:changeCard(valueTemp);
							table.insert(removedCardList,laiziCard);
						end

						for _,laiziCard in ipairs(useLaiziCardList) do
							laiziCard:changeCard(laiziCard:getValue());
						end

						local tupleCards = pokercore.new(Cards,removedCardList);
						local remainCards = DdzTypeUtil.cloneCardsAndAddCardList(modelCardsCopy, useLaiziCardList);
						local takenCardsList = fourTakeSingleTypeAnalyzer:repeatSelectSingleCards(remainCards, 1, term);
						for _, takenCards in ipairs(takenCardsList) do
							local resultCards = DdzTypeUtil.cloneCardsAndAddCards(tupleCards, takenCards);
							local key = valueTemp * TUPLE_WEIGHT;
							for _,card in ipairs(takenCards.cardList) do
								key = key + card:getValue();
								if card:isLazi() then -- // 癞子权重，区分癞子变成的5 和 原本就是5
									key = key + card:getValue() * LAIZI_WEIGHT;
								end
							end
							if not exsitKeys[key] and self:match(resultCards, term) then
								exsitKeys[key] = true;
								self:analysize(resultCards, term);
								table.insert(cardsResult,resultCards);
							end
						end


					 end
				end
			end
		else -- // 用了 4个癞子
			for valueTemp = PokerGameConstant.NUMBER_3_VALUE --// 从小开始
					,PokerGameConstant.NUMBER_2_VALUE  do
				local modelCardsCopy = laiziCards:clone(); --// 常规牌补上癞子
				local modelResultCopy =  modelCardsCopy:getResult();
				if (modelResultCopy:getAllValueCounter():getValueCount(valueTemp) >= ThreeTypeAnalyzer.TUPLE_SIZE) then
					local removedCardList = DdzTypeUtil.cloneRemovedCards(modelCardsCopy, valueTemp, ThreeTypeAnalyzer.TUPLE_SIZE);
					local tupleCards = pokercore.new(Cards,removedCardList);
					local takenCardsList = fourTakeSingleTypeAnalyzer:repeatSelectSingleCards(modelCardsCopy, 1, term);

					for _,takenCards in ipairs(takenCardsList) do
						local resultCards = DdzTypeUtil.cloneCardsAndAddCards(tupleCards, takenCards);
						for _,card in ipairs(resultCards) do
							if card:hasNotChanged() then -- // 有的经过处理已经被赋值了不能再改变
								card:changeCard(card:getValue());
							end
						end
						if (self:match(resultCards, term)) then
							self:analysize(resultCards, term);
							table.insert(cardsResult,resultCards);
						end
					end
				end
			end
		end
	end
	return cardsResult;
end


return ThreeTakeSingleTypeAnalyzer;

